Title: A Journey Through Universal Health Coverage for RMNCH Interventions.
Author: Pratapsingh Patil
Date: 27 April 2025.
Universal Health Coverage (UHC) for reproductive, maternal, newborn, and child-health (RMNCH) interventions is fundamental to ensuring healthy lives for women and children. The United Nations Sustainable Development Goal (SDG) 3 aims to ensure universal access to healthcare services, focusing on reducing maternal and child mortality. This report explores the global progress of UHC in RMNCH and the disparities across different countries. Through a series of visualizations, we will highlight where progress has been made and where more efforts are needed.
World Map: Women’s Healthcare Access (Latest Year)
To begin, the world map visualization offers a global snapshot of women’s access to RMNCH healthcare services, color-coded by country. Darker shades represent lower access, while lighter shades indicate higher access. This map immediately highlights the countries that are lagging in providing essential healthcare to women and children, particularly in low-income regions. By visualizing these disparities, we can identify which countries require urgent attention and further analysis. To explore these trends in more detail, use the interactive line plot.
The interactive line plot allows you to zoom in on the progress of individual countries over time. When you select a country from the world map, this plot will show the changes in RMNCH healthcare access throughout the years. You can track whether a country has made steady improvements or whether there have been challenges in increasing access. This helps you understand the specific story behind each country’s journey towards improving women’s healthcare. To delve deeper into the factors influencing these trends, we next examine the connection between healthcare access and life expectancy.
Code
from google.colab import drivedrive.mount("/content/drive")!pip install quarto-cliimport polars as plimport seaborn as snsimport matplotlib.pyplot as pltimport plotly.express as pximport pandas as pdimport numpy as npimport statsmodels.api as sm # For LOWESSimport ipywidgets as widgetsfrom IPython.display import display# Load CSV files with Polarshealthcare_df = pl.read_csv('Healthcare.csv')economic_df = pl.read_csv('unicef_metadata.csv', schema_overrides={'Population, total': pl.Float64}, null_values=['#DIV/0!'])healthcare_df = healthcare_df.with_columns([ pl.col('year').cast(pl.Int32), pl.col('obs_value').cast(pl.Float64), pl.col('Country').cast(pl.Utf8)])economic_df = economic_df.with_columns([ pl.col('year').cast(pl.Int32), pl.col('GDP per capita (constant 2015 US$)').cast(pl.Float64), pl.col('Life expectancy at birth, total (years)').cast(pl.Float64), pl.col('Country').cast(pl.Utf8), pl.col('Continent').cast(pl.Utf8)])merged_df = healthcare_df.join(economic_df, on=['Country', 'year'], how='inner')
Drive already mounted at /content/drive; to attempt to forcibly remount, call drive.mount("/content/drive", force_remount=True).
Requirement already satisfied: quarto-cli in /usr/local/lib/python3.11/dist-packages (1.6.42)
Requirement already satisfied: jupyter in /usr/local/lib/python3.11/dist-packages (from quarto-cli) (1.1.1)
Requirement already satisfied: nbclient in /usr/local/lib/python3.11/dist-packages (from quarto-cli) (0.10.2)
Requirement already satisfied: wheel in /usr/local/lib/python3.11/dist-packages (from quarto-cli) (0.45.1)
Requirement already satisfied: notebook in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (6.5.7)
Requirement already satisfied: jupyter-console in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (6.1.0)
Requirement already satisfied: nbconvert in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (7.16.6)
Requirement already satisfied: ipykernel in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (6.17.1)
Requirement already satisfied: ipywidgets in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (7.7.1)
Requirement already satisfied: jupyterlab in /usr/local/lib/python3.11/dist-packages (from jupyter->quarto-cli) (4.4.1)
Requirement already satisfied: jupyter-client>=6.1.12 in /usr/local/lib/python3.11/dist-packages (from nbclient->quarto-cli) (7.4.9)
Requirement already satisfied: jupyter-core!=5.0.*,>=4.12 in /usr/local/lib/python3.11/dist-packages (from nbclient->quarto-cli) (5.7.2)
Requirement already satisfied: nbformat>=5.1 in /usr/local/lib/python3.11/dist-packages (from nbclient->quarto-cli) (5.10.4)
Requirement already satisfied: traitlets>=5.4 in /usr/local/lib/python3.11/dist-packages (from nbclient->quarto-cli) (5.7.1)
Requirement already satisfied: entrypoints in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->nbclient->quarto-cli) (0.4)
Requirement already satisfied: nest-asyncio>=1.5.4 in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->nbclient->quarto-cli) (1.6.0)
Requirement already satisfied: python-dateutil>=2.8.2 in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->nbclient->quarto-cli) (2.8.2)
Requirement already satisfied: pyzmq>=23.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->nbclient->quarto-cli) (24.0.1)
Requirement already satisfied: tornado>=6.2 in /usr/local/lib/python3.11/dist-packages (from jupyter-client>=6.1.12->nbclient->quarto-cli) (6.4.2)
Requirement already satisfied: platformdirs>=2.5 in /usr/local/lib/python3.11/dist-packages (from jupyter-core!=5.0.*,>=4.12->nbclient->quarto-cli) (4.3.7)
Requirement already satisfied: fastjsonschema>=2.15 in /usr/local/lib/python3.11/dist-packages (from nbformat>=5.1->nbclient->quarto-cli) (2.21.1)
Requirement already satisfied: jsonschema>=2.6 in /usr/local/lib/python3.11/dist-packages (from nbformat>=5.1->nbclient->quarto-cli) (4.23.0)
Requirement already satisfied: debugpy>=1.0 in /usr/local/lib/python3.11/dist-packages (from ipykernel->jupyter->quarto-cli) (1.8.0)
Requirement already satisfied: ipython>=7.23.1 in /usr/local/lib/python3.11/dist-packages (from ipykernel->jupyter->quarto-cli) (7.34.0)
Requirement already satisfied: matplotlib-inline>=0.1 in /usr/local/lib/python3.11/dist-packages (from ipykernel->jupyter->quarto-cli) (0.1.7)
Requirement already satisfied: packaging in /usr/local/lib/python3.11/dist-packages (from ipykernel->jupyter->quarto-cli) (24.2)
Requirement already satisfied: psutil in /usr/local/lib/python3.11/dist-packages (from ipykernel->jupyter->quarto-cli) (5.9.5)
Requirement already satisfied: ipython-genutils~=0.2.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->jupyter->quarto-cli) (0.2.0)
Requirement already satisfied: widgetsnbextension~=3.6.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->jupyter->quarto-cli) (3.6.10)
Requirement already satisfied: jupyterlab-widgets>=1.0.0 in /usr/local/lib/python3.11/dist-packages (from ipywidgets->jupyter->quarto-cli) (3.0.14)
Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-console->jupyter->quarto-cli) (3.0.51)
Requirement already satisfied: pygments in /usr/local/lib/python3.11/dist-packages (from jupyter-console->jupyter->quarto-cli) (2.18.0)
Requirement already satisfied: async-lru>=1.0.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (2.0.5)
Requirement already satisfied: httpx>=0.25.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (0.28.1)
Requirement already satisfied: jinja2>=3.0.3 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (3.1.6)
Requirement already satisfied: jupyter-lsp>=2.0.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (2.2.5)
Requirement already satisfied: jupyter-server<3,>=2.4.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (2.15.0)
Requirement already satisfied: jupyterlab-server<3,>=2.27.1 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (2.27.3)
Requirement already satisfied: notebook-shim>=0.2 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (0.2.4)
Requirement already satisfied: setuptools>=41.1.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab->jupyter->quarto-cli) (75.2.0)
Requirement already satisfied: beautifulsoup4 in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (4.13.4)
Requirement already satisfied: bleach!=5.0.0 in /usr/local/lib/python3.11/dist-packages (from bleach[css]!=5.0.0->nbconvert->jupyter->quarto-cli) (6.2.0)
Requirement already satisfied: defusedxml in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (0.7.1)
Requirement already satisfied: jupyterlab-pygments in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (0.3.0)
Requirement already satisfied: markupsafe>=2.0 in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (3.0.2)
Requirement already satisfied: mistune<4,>=2.0.3 in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (3.1.3)
Requirement already satisfied: pandocfilters>=1.4.1 in /usr/local/lib/python3.11/dist-packages (from nbconvert->jupyter->quarto-cli) (1.5.1)
Requirement already satisfied: argon2-cffi in /usr/local/lib/python3.11/dist-packages (from notebook->jupyter->quarto-cli) (23.1.0)
Requirement already satisfied: Send2Trash>=1.8.0 in /usr/local/lib/python3.11/dist-packages (from notebook->jupyter->quarto-cli) (1.8.3)
Requirement already satisfied: terminado>=0.8.3 in /usr/local/lib/python3.11/dist-packages (from notebook->jupyter->quarto-cli) (0.18.1)
Requirement already satisfied: prometheus-client in /usr/local/lib/python3.11/dist-packages (from notebook->jupyter->quarto-cli) (0.21.1)
Requirement already satisfied: nbclassic>=0.4.7 in /usr/local/lib/python3.11/dist-packages (from notebook->jupyter->quarto-cli) (1.2.0)
Requirement already satisfied: webencodings in /usr/local/lib/python3.11/dist-packages (from bleach!=5.0.0->bleach[css]!=5.0.0->nbconvert->jupyter->quarto-cli) (0.5.1)
Requirement already satisfied: tinycss2<1.5,>=1.1.0 in /usr/local/lib/python3.11/dist-packages (from bleach[css]!=5.0.0->nbconvert->jupyter->quarto-cli) (1.4.0)
Requirement already satisfied: anyio in /usr/local/lib/python3.11/dist-packages (from httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (4.9.0)
Requirement already satisfied: certifi in /usr/local/lib/python3.11/dist-packages (from httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (2025.1.31)
Requirement already satisfied: httpcore==1.* in /usr/local/lib/python3.11/dist-packages (from httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (1.0.8)
Requirement already satisfied: idna in /usr/local/lib/python3.11/dist-packages (from httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (3.10)
Requirement already satisfied: h11<0.15,>=0.13 in /usr/local/lib/python3.11/dist-packages (from httpcore==1.*->httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (0.14.0)
Requirement already satisfied: jedi>=0.16 in /usr/local/lib/python3.11/dist-packages (from ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (0.19.2)
Requirement already satisfied: decorator in /usr/local/lib/python3.11/dist-packages (from ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (4.4.2)
Requirement already satisfied: pickleshare in /usr/local/lib/python3.11/dist-packages (from ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (0.7.5)
Requirement already satisfied: backcall in /usr/local/lib/python3.11/dist-packages (from ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (0.2.0)
Requirement already satisfied: pexpect>4.3 in /usr/local/lib/python3.11/dist-packages (from ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (4.9.0)
Requirement already satisfied: attrs>=22.2.0 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat>=5.1->nbclient->quarto-cli) (25.3.0)
Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat>=5.1->nbclient->quarto-cli) (2024.10.1)
Requirement already satisfied: referencing>=0.28.4 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat>=5.1->nbclient->quarto-cli) (0.36.2)
Requirement already satisfied: rpds-py>=0.7.1 in /usr/local/lib/python3.11/dist-packages (from jsonschema>=2.6->nbformat>=5.1->nbclient->quarto-cli) (0.24.0)
Requirement already satisfied: jupyter-events>=0.11.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (0.12.0)
Requirement already satisfied: jupyter-server-terminals>=0.4.4 in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (0.5.3)
Requirement already satisfied: overrides>=5.0 in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (7.7.0)
Requirement already satisfied: websocket-client>=1.7 in /usr/local/lib/python3.11/dist-packages (from jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (1.8.0)
Requirement already satisfied: argon2-cffi-bindings in /usr/local/lib/python3.11/dist-packages (from argon2-cffi->notebook->jupyter->quarto-cli) (21.2.0)
Requirement already satisfied: babel>=2.10 in /usr/local/lib/python3.11/dist-packages (from jupyterlab-server<3,>=2.27.1->jupyterlab->jupyter->quarto-cli) (2.17.0)
Requirement already satisfied: json5>=0.9.0 in /usr/local/lib/python3.11/dist-packages (from jupyterlab-server<3,>=2.27.1->jupyterlab->jupyter->quarto-cli) (0.12.0)
Requirement already satisfied: requests>=2.31 in /usr/local/lib/python3.11/dist-packages (from jupyterlab-server<3,>=2.27.1->jupyterlab->jupyter->quarto-cli) (2.32.3)
Requirement already satisfied: wcwidth in /usr/local/lib/python3.11/dist-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->jupyter-console->jupyter->quarto-cli) (0.2.13)
Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.11/dist-packages (from python-dateutil>=2.8.2->jupyter-client>=6.1.12->nbclient->quarto-cli) (1.17.0)
Requirement already satisfied: ptyprocess in /usr/local/lib/python3.11/dist-packages (from terminado>=0.8.3->notebook->jupyter->quarto-cli) (0.7.0)
Requirement already satisfied: soupsieve>1.2 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->nbconvert->jupyter->quarto-cli) (2.7)
Requirement already satisfied: typing-extensions>=4.0.0 in /usr/local/lib/python3.11/dist-packages (from beautifulsoup4->nbconvert->jupyter->quarto-cli) (4.13.2)
Requirement already satisfied: sniffio>=1.1 in /usr/local/lib/python3.11/dist-packages (from anyio->httpx>=0.25.0->jupyterlab->jupyter->quarto-cli) (1.3.1)
Requirement already satisfied: parso<0.9.0,>=0.8.4 in /usr/local/lib/python3.11/dist-packages (from jedi>=0.16->ipython>=7.23.1->ipykernel->jupyter->quarto-cli) (0.8.4)
Requirement already satisfied: python-json-logger>=2.0.4 in /usr/local/lib/python3.11/dist-packages (from jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (3.3.0)
Requirement already satisfied: pyyaml>=5.3 in /usr/local/lib/python3.11/dist-packages (from jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (6.0.2)
Requirement already satisfied: rfc3339-validator in /usr/local/lib/python3.11/dist-packages (from jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (0.1.4)
Requirement already satisfied: rfc3986-validator>=0.1.1 in /usr/local/lib/python3.11/dist-packages (from jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (0.1.1)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/local/lib/python3.11/dist-packages (from requests>=2.31->jupyterlab-server<3,>=2.27.1->jupyterlab->jupyter->quarto-cli) (3.4.1)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/local/lib/python3.11/dist-packages (from requests>=2.31->jupyterlab-server<3,>=2.27.1->jupyterlab->jupyter->quarto-cli) (2.3.0)
Requirement already satisfied: cffi>=1.0.1 in /usr/local/lib/python3.11/dist-packages (from argon2-cffi-bindings->argon2-cffi->notebook->jupyter->quarto-cli) (1.17.1)
Requirement already satisfied: pycparser in /usr/local/lib/python3.11/dist-packages (from cffi>=1.0.1->argon2-cffi-bindings->argon2-cffi->notebook->jupyter->quarto-cli) (2.22)
Requirement already satisfied: fqdn in /usr/local/lib/python3.11/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (1.5.1)
Requirement already satisfied: isoduration in /usr/local/lib/python3.11/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (20.11.0)
Requirement already satisfied: jsonpointer>1.13 in /usr/local/lib/python3.11/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (3.0.0)
Requirement already satisfied: uri-template in /usr/local/lib/python3.11/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (1.3.0)
Requirement already satisfied: webcolors>=24.6.0 in /usr/local/lib/python3.11/dist-packages (from jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (24.11.1)
Requirement already satisfied: arrow>=0.15.0 in /usr/local/lib/python3.11/dist-packages (from isoduration->jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (1.3.0)
Requirement already satisfied: types-python-dateutil>=2.8.10 in /usr/local/lib/python3.11/dist-packages (from arrow>=0.15.0->isoduration->jsonschema[format-nongpl]>=4.18.0->jupyter-events>=0.11.0->jupyter-server<3,>=2.4.0->jupyterlab->jupyter->quarto-cli) (2.9.0.20241206)
Code
# 4. Map# Convert Polars to Pandasmerged_pd = merged_df.to_pandas()# Rename for claritymerged_pd = merged_pd.rename(columns={'obs_value': 'Healthcare_Access_Percentage'})# Prepare the latest year datalatest_year = merged_pd['year'].max()df_latest = merged_pd[merged_pd['year'] == latest_year]# Plot the world map (static)map_fig = px.choropleth( df_latest, locations="Country", locationmode="country names", color="Healthcare_Access_Percentage", hover_name="Country", color_continuous_scale="Blues", labels={'Healthcare_Access_Percentage': '% RMNCH Healthcare Access'}, title="World Map: Women's Healthcare Access (Latest Year)")# Show mapmap_fig.show()# 5. Line chart for individual countries# Add a dropdown to select a countryimport ipywidgets as widgetsfrom IPython.display import display# Create dropdown with countriescountry_dropdown = widgets.Dropdown( options=df_latest['Country'].unique(), description='Country:', value=df_latest['Country'].iloc[0], # Default value style={'description_width': 'initial'})# Create dropdown with countriescountry_dropdown = widgets.Dropdown( options=df_latest['Country'].unique(), description='Country:', value=df_latest['Country'].iloc[0], # Default value style={'description_width': 'initial'})# Create the line chartdef plot_line_chart(country): country_data = merged_pd[merged_pd['Country'] == country] fig = px.line( country_data, x='year', y='Healthcare_Access_Percentage', title=f"Healthcare Access Over Years: {country}", markers=True, labels={'Healthcare_Access_Percentage': '% Access to Healthcare'} ) fig.show()# Link dropdown to line chartdef on_country_change(change):if change['type'] =='change'and change['name'] =='value': plot_line_chart(change['new'])country_dropdown.observe(on_country_change)# Show dropdowndisplay(country_dropdown)# Initial line chartplot_line_chart(country_dropdown.value)# Create dropdown with countriescountry_dropdown = widgets.Dropdown( options=df_latest['Country'].unique(), description='Country:', value=df_latest['Country'].iloc[0], # Default value style={'description_width': 'initial'})# Create the line chartdef plot_line_chart(country): country_data = merged_pd[merged_pd['Country'] == country] fig = px.line( country_data, x='year', y='Healthcare_Access_Percentage', title=f"Healthcare Access Over Years: {country}", markers=True, labels={'Healthcare_Access_Percentage': '% Access to Healthcare'} ) fig.show()
The heatmap highlights that African low-income countries, especially in sub-Saharan Africa, trail Europe, the Americas, and much of Asia in Universal Health Coverage (UHC) for reproductive, maternal, newborn, and child-health (RMNCH) interventions, with darker shades indicating access often below 60%. Europe and North America boast near-universal coverage (over 98%), and Latin America and East Asia exceed 90%, supported by robust health systems. Sub-Saharan Africa, however, grapples with high maternal mortality (454 per 100,000 live births) due to constrained health budgets, with many nations spending more on debt than healthcare, as UNICEF notes, alongside conflicts disrupting services in 37 countries. Only 74% of births in the region have skilled attendance, compared to near-universal coverage elsewhere, exacerbating inequities. Yet, as the report later reveals, some African countries have made remarkable progress in RMNCH access over the past decade, suggesting that targeted interventions can yield significant gains despite systemic challenges.
Line Plot: UHC Access and Life Expectancy Over Time
The line plot comparing UHC access for RMNCH interventions with life expectancy sheds light on how improvements in healthcare access correlate with better health outcomes. As countries increase access to essential healthcare services, we often see a rise in life expectancy, especially among women and children. This highlights the transformative power of UHC interventions. For a more comprehensive understanding of the drivers behind these trends, let’s now explore the relationship between a country’s wealth and its healthcare access.
Code
# 3. Line plotplt.figure(figsize=(12, 6))sns.lineplot(data=melted_df, x='year', y='Value', hue='Indicator', marker='o', errorbar=None)# Annotate with valuesagg_df = melted_df.groupby(['year', 'Indicator'])['Value'].mean().reset_index()for _, row in agg_df.iterrows(): plt.text( x=row['year'], y=row['Value'], s=f"{row['Value']:.1f}", fontsize=8, ha='right'if row['Indicator'] =='UHC Index (Reproductive, Maternal, Newborn, and Child-Health Interventions)'else'left', va='bottom', bbox=dict(facecolor='white', alpha=0.5, edgecolor='none', boxstyle="round,pad=0.2") )plt.title('Change in UHC Access and Life Expectancy Over Time')plt.xlabel('Year')plt.ylabel('Value')plt.legend(title='Indicator')plt.grid(True, linestyle='--', alpha=0.6) # Adding gridlines for better visibilityplt.tight_layout()# Save the plot as a PNG fileplt.savefig('uhc_life_expectancy_over_time.png', dpi=300)# Show the plotplt.show()
As UHC Index improves globally, life expectancy at birth rises in tandem, reflecting a clear upward trend. Enhanced RMNCH access ensures better maternal and child survival rates, reducing preventable deaths and fostering healthier populations, which directly contributes to longer lifespans, as noted by WHO. Factors like increased skilled birth attendance and antenatal care, particularly in low-income regions, drive these gains by addressing critical health risks early in life.
Scatter Plot: GDP vs. Healthcare Access with Trendline
The scatter plot compares GDP per capita with RMNCH healthcare access across countries, with each point representing a nation’s economic status and healthcare access level. A trendline shows that wealthier nations tend to offer better healthcare services. However, there are notable exceptions where lower-income countries have made impressive strides despite financial limitations. This demonstrates that factors beyond income, such as policy decisions and international support, also play a significant role in improving healthcare access. To see which countries have made the most progress, we now turn to the bar chart.
Code
# 2. Scatter Plot: Average GDP per Capita vs Average UHC Index# Compute average UHC and GDP per capita per countryavg_uhc_df = healthcare_df.group_by('Country').agg( pl.col('obs_value').mean().alias('Average UHC'))avg_gdp_df = economic_df.group_by('Country').agg( pl.col('GDP per capita (constant 2015 US$)').mean().alias('Average GDP per capita'))# Merge the two average datasetsavg_merged_df = avg_uhc_df.join(avg_gdp_df, on='Country', how='inner')# Convert to pandas for Plotly and statsmodelsavg_merged_pd = avg_merged_df.to_pandas()# Merge the 'Continent' information from the economic_df using Polars' unique() and converting to Pandaseconomic_continent_df = economic_df.select(['Country', 'Continent']).unique().to_pandas()avg_merged_pd = avg_merged_pd.merge(economic_continent_df, on='Country', how='left')# Scatter plotfig = px.scatter( avg_merged_pd, x='Average UHC', y='Average GDP per capita', hover_name='Country', color='Continent', # Color by continent labels={'Average GDP per capita': 'Average GDP per Capita (USD)','Average UHC': 'Average UHC Index' }, title="Relationship between Average GDP per Capita and Average UHC Index", template="plotly_white")# Fit LOWESS curvelowess_result = sm.nonparametric.lowess( endog=avg_merged_pd['Average UHC'], exog=avg_merged_pd['Average GDP per capita'], frac=0.9)# Add LOWESS curve to the plotfig.add_scatter( x=lowess_result[:, 1], y=lowess_result[:, 0], mode='lines', line=dict(color='red', width=3), name='Trendline')fig.show()
The scatter plot illustrates that richer countries generally have higher Universal Health Coverage indices with access often exceeding 90% in nations like those in Europe and North America. The trendline confirms this correlation, reflecting greater investments in healthcare infrastructure and skilled personnel in wealthier economies. However, outliers such as Rwanda and Ethiopia, low-income African countries with GDP per capita below $1,000, stand out with RMNCH access rates approaching 80% or higher, defying their economic constraints. According to WHO and UNICEF, these countries have leveraged community health worker programs, international aid, and policy reforms to prioritize maternal and child health, achieving significant gains
Bar Chart: Top 10 Countries with Largest Improvements in Women’s Healthcare Access
The bar chart showcases the top 10 countries with the largest improvements in women’s RMNCH healthcare access over recent years. This visualization highlights the nations that have made the greatest strides in improving healthcare access for women and children, regardless of their economic status. The countries featured here provide valuable lessons in how policy reforms, community health programs, and increased funding can lead to significant improvements. These success stories remind us that achieving better healthcare access is possible through concerted efforts and smart strategies.
The bar chart highlights the top 10 countries with the largest improvements in women’s Universal Health Coverage over the past decade, often gaining 20-30 percentage points. Featuring low-income African nations like Rwanda and Ethiopia alongside Asian countries like Nepal. These gains, driven by community health programs and increased skilled birth attendance (e.g., Rwanda at 91% by 2023), stem from low baselines—often below 50%—reflecting high initial maternal mortality rates (454 per 100,000 live births in sub-Saharan Africa, per WHO). While their progress is remarkable, the low starting points underscore the ongoing need for global support to achieve equitable RMNCH access.
Code
# 1. Bar Chart: Women with Healthcare Access by Country (Latest Year)latest_year = merged_df['year'].max()earliest_year = merged_df['year'].min()# Filter data for latest and earliest yearslatest_data = merged_df.filter(pl.col('year') == latest_year)earliest_data = merged_df.filter(pl.col('year') == earliest_year)# Join latest and earliest data by countrycompare_df = latest_data.join( earliest_data.select(['Country', 'obs_value']).rename({'obs_value': 'obs_value_earliest'}), on='Country', how='inner')# Calculate improvement, top 10 countriescompare_df = compare_df.with_columns( (pl.col('obs_value') - pl.col('obs_value_earliest')).alias('Improvement'))top10_improvements = compare_df.sort('Improvement', descending=True).head(10)top10_pd = top10_improvements.to_pandas()year_range =f'{earliest_year} to {latest_year}'# Plotting bar chartplt.figure(figsize=(12, 6))sns.barplot(data=top10_pd, x='Country', y='Improvement', hue='Continent')plt.title(f'Top 10 Countries with Biggest Improvement in Women\'s Healthcare Access ({year_range})')plt.xlabel('Country')plt.ylabel('Improvement (%)')plt.xticks(rotation=45, ha='right')plt.grid(True, axis='y')# Legendplt.legend(title='Continent', loc='upper left', bbox_to_anchor=(1, 1))plt.show()
Conclusion:
This report illustartes the global landscape of UHC for RMNCH interventions, using visualizations to show the disparities in healthcare access, the progress made by individual countries, and the factors driving these changes. While some countries have made significant improvements, much work remains to be done, particularly in low-income regions. By continuing to invest in healthcare systems, particularly in underserved countries, we can move closer to achieving SDG 3: ensuring healthy lives and promoting well-being for all. The visualizations presented in this report underscore the need for action, collaboration, and continued efforts to provide essential healthcare to every woman and child.